/**
 * 网络测速功能模块
 * 
 * 这个模块包含了网络测速的核心逻辑。它通过IPC与主进程通信，
 * 并使用Electron的API来获取网络信息。测速结果通过IPC传递给渲染进程，
 * 并在UI上显示。
 */

const { ipcRenderer } = require('electron');
const { handleError, ErrorTypes, tryCatch } = require('../../common/error-handler');
const { showToast } = require('../../common/show-toast');
const { NetworkChannels } = require('../../common/ipc-channels');
// 网络测速功能
function initialize() {
    const startTestBtn = document.getElementById('btn-start-test');
    const downloadSpeedEl = document.getElementById('download-speed');
    const uploadSpeedEl = document.getElementById('upload-speed');
    const pingValueEl = document.getElementById('ping-value');
    const downloadGaugeEl = document.getElementById('download-gauge');
    const uploadGaugeEl = document.getElementById('upload-gauge');
    const localIpEl = document.getElementById('local-ip');
    const publicIpEl = document.getElementById('public-ip');

    // 用于存储事件监听器引用，便于清理
    let speedTestProgressListener = null;
    let speedTestResultListener = null;
    let ipAddressResultListener = null;

    // 加载历史记录
    const loadHistory = () => {
        const history = JSON.parse(localStorage.getItem('network-speed-history') || '[]');
        updateHistoryTable(history);
    };

    // 更新历史表格
    const updateHistoryTable = (history) => {
        const historyTable = document.querySelector('.speed-test-history-table');
        if (!historyTable) return;

        const tbody = historyTable.querySelector('tbody');
        if (!tbody) return;

        tbody.innerHTML = '';

        // 倒序显示历史记录，最新的在最前面
        history.slice().reverse().forEach(record => {
            const row = document.createElement('tr');
            row.innerHTML = `
                <td>${record.time}</td>
                <td>${record.download} Mbps</td>
                <td>${record.upload} Mbps</td>
                <td>${record.ping} ms</td>
            `;
            tbody.appendChild(row);
        });
    };

    // 添加新记录到历史
    const addToHistory = (download, upload, ping) => {
        const now = new Date();
        const timeStr = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')} ${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;

        const history = JSON.parse(localStorage.getItem('network-speed-history') || '[]');

        // 检查是否存在相同时间的记录
        const existingRecord = history.find(record => record.time === timeStr);

        // 如果不存在相同时间的记录,或者存在但数据不同,则添加新记录
        if (!existingRecord ||
            existingRecord.download !== download ||
            existingRecord.upload !== upload ||
            existingRecord.ping !== ping) {
            history.push({
                time: timeStr,
                download: download,
                upload: upload,
                ping: ping
            });
        }

        // 只保留最近50条记录
        if (history.length > 50) {
            history.shift();
        }

        localStorage.setItem('network-speed-history', JSON.stringify(history));
        updateHistoryTable(history);
    };

    // 清理所有测速相关的事件监听器
    const clearSpeedTestListeners = () => {
        if (speedTestProgressListener) {
            ipcRenderer.removeListener(NetworkChannels.TEST_NETWORK_SPEED + '-progress', speedTestProgressListener);
            speedTestProgressListener = null;
        }

        if (speedTestResultListener) {
            ipcRenderer.removeListener(NetworkChannels.TEST_NETWORK_SPEED + '-result', speedTestResultListener);
            speedTestResultListener = null;
        }

        if (ipAddressResultListener) {
            ipcRenderer.removeListener(NetworkChannels.TEST_NETWORK_SPEED + '-ip-address', ipAddressResultListener);
            ipAddressResultListener = null;
        }

        // 确保无论如何都重置按钮状态
        startTestBtn.disabled = false;
        startTestBtn.innerHTML = '<i class="fas fa-play"></i> 开始测速';
    };

    // 重置UI显示
    const resetSpeedTestUI = () => {
        downloadSpeedEl.textContent = "--";
        uploadSpeedEl.textContent = "--";
        pingValueEl.textContent = "--";
        downloadGaugeEl.style.height = "0%";
        uploadGaugeEl.style.height = "0%";

        // 重置ping值颜色
        pingValueEl.style.color = '';

        // 移除进度指示器
        const progressIndicator = document.getElementById('test-progress-indicator');
        if (progressIndicator) {
            progressIndicator.style.display = 'none';
        }

        // 隐藏网络信息
        const networkInfoEl = document.getElementById('network-info');
        if (networkInfoEl) {
            networkInfoEl.style.display = 'none';
        }

        // 移除抖动显示
        const jitterEl = document.getElementById('jitter-value');
        if (jitterEl) {
            const jitterContainer = jitterEl.closest('.jitter-container');
            if (jitterContainer) {
                jitterContainer.remove();
            }
        }

        // 更新IP地址显示
        localIpEl.textContent = "获取中...";
        publicIpEl.textContent = "获取中...";

        // 更新按钮状态
        startTestBtn.disabled = false;
        startTestBtn.innerHTML = '<i class="fas fa-play"></i> 开始测速';
    };

    // 数字动画函数 - 使数值从startValue平滑过渡到endValue
    const animateValue = (element, startValue, endValue, duration, format) => {
        // 保存动画ID，方便在必要时取消
        let animationId;

        // 如果该元素上有进行中的动画，取消它
        if (element._animationId) {
            cancelAnimationFrame(element._animationId);
        }

        // 初始化动画参数
        const startTime = performance.now();

        // 创建动画帧
        const animateFrame = (currentTime) => {
            // 计算动画进行时间
            const elapsedTime = currentTime - startTime;

            // 计算完成比例
            const progress = Math.min(elapsedTime / duration, 1);

            // 计算当前值 (使用easeOutCubic缓动函数使动画更自然)
            const easeOutCubic = 1 - Math.pow(1 - progress, 3);
            const currentValue = startValue + (endValue - startValue) * easeOutCubic;

            // 格式化并更新显示
            const formattedValue = format ? format(currentValue) : currentValue;
            element.textContent = formattedValue;

            // 如果动画未完成，请求下一帧
            if (progress < 1) {
                element._animationId = requestAnimationFrame(animateFrame);
            } else {
                // 动画完成，清除animationId
                delete element._animationId;
            }
        };

        // 启动动画
        element._animationId = requestAnimationFrame(animateFrame);
    };

    // 执行网络测速
    const runSpeedTest = () => {
        // 清理之前的事件监听器
        clearSpeedTestListeners();

        // 重置显示
        resetSpeedTestUI();

        // 更新按钮状态
        startTestBtn.disabled = true;
        startTestBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 测试中...';

        // 显示提示消息
        showToast('测速开始，请稍候...', 'info');

        // 创建测试进度指示器(如果不存在)
        let progressIndicator = document.getElementById('test-progress-indicator');
        if (!progressIndicator) {
            progressIndicator = document.createElement('div');
            progressIndicator.id = 'test-progress-indicator';
            progressIndicator.className = 'test-progress-indicator';
            document.querySelector('.speed-test-container').appendChild(progressIndicator);
        }

        progressIndicator.innerHTML = '<div class="progress-label">准备测速...</div><div class="progress-bar-container"><div class="progress-bar-fill"></div><div class="progress-percentage">0%</div></div>';
        progressIndicator.style.display = 'block';

        // 设置进度条动画
        const progressBar = progressIndicator.querySelector('.progress-bar-fill');
        const progressPercentage = progressIndicator.querySelector('.progress-percentage');
        progressBar.style.width = '5%';
        progressPercentage.textContent = '5%';

        // 创建网络信息显示区域(如果不存在)
        let networkInfoEl = document.getElementById('network-info');
        if (!networkInfoEl) {
            networkInfoEl = document.createElement('div');
            networkInfoEl.id = 'network-info';
            networkInfoEl.className = 'network-info';
            document.querySelector('.speed-test-container').appendChild(networkInfoEl);
        }

        networkInfoEl.innerHTML = '';
        networkInfoEl.style.display = 'none';

        // 创建动画状态标志，用于控制三个卡片的动画状态
        const animationState = {
            downloadAnimationActive: true,
            uploadAnimationActive: true,
            pingAnimationActive: true
        };

        // 初始化测试数值动画
        // 启动下载速度数字动画
        let downloadAnimationId = null;
        let downloadFrameCount = 0; // 添加帧计数器
        const animateDownload = () => {
            if (!animationState.downloadAnimationActive) return;

            // 每隔1帧才更新一次数值，降低动画速度
            downloadFrameCount++;
            if (downloadFrameCount % 6 === 0) {
                const randomDownload = Math.random() * 10 + 50; // 50-60范围的随机值
                downloadSpeedEl.textContent = randomDownload.toFixed(2);
                downloadGaugeEl.style.height = `${Math.min(randomDownload / 1.5, 100)}%`;
            }

            downloadAnimationId = requestAnimationFrame(animateDownload);
        };
        downloadAnimationId = requestAnimationFrame(animateDownload);

        // 初始化上传速度动画
        let uploadAnimationId = null;
        let uploadFrameCount = 0; // 添加帧计数器
        const animateUpload = () => {
            if (!animationState.uploadAnimationActive) return;

            // 每隔1帧才更新一次数值，降低动画速度
            uploadFrameCount++;
            if (uploadFrameCount % 6 === 0) {
                const randomUpload = Math.random() * 10 + 25; // 25-35范围的随机值
                uploadSpeedEl.textContent = randomUpload.toFixed(2);
                uploadGaugeEl.style.height = `${Math.min(randomUpload / 0.75, 100)}%`;
            }

            uploadAnimationId = requestAnimationFrame(animateUpload);
        };
        setTimeout(() => {
            uploadAnimationId = requestAnimationFrame(animateUpload);
        }, 500);

        // 初始化延迟动画
        let pingAnimationId = null;
        let pingFrameCount = 0; // 添加帧计数器
        const animatePing = () => {
            if (!animationState.pingAnimationActive) return;

            // 每隔1帧才更新一次数值，降低动画速度
            pingFrameCount++;
            if (pingFrameCount % 6 === 0) {
                const pingVariation = Math.floor(Math.random() * 10 - 5); // -5到5之间的随机变化
                const currentPing = parseInt(pingValueEl.textContent) || 50;
                const newPing = Math.max(10, Math.min(200, currentPing + pingVariation)); // 限制在10-200ms范围内
                pingValueEl.textContent = newPing;

                // 更新颜色
                if (newPing < 50) {
                    pingValueEl.style.color = '#27ae60'; // 良好延迟-绿色
                } else if (newPing < 100) {
                    pingValueEl.style.color = '#f39c12'; // 一般延迟-黄色
                } else {
                    pingValueEl.style.color = '#e74c3c'; // 高延迟-红色
                }
            }

            pingAnimationId = requestAnimationFrame(animatePing);
        };
        setTimeout(() => {
            pingValueEl.textContent = "50";
            pingAnimationId = requestAnimationFrame(animatePing);
        }, 1000);

        // 监听测试进度更新
        speedTestProgressListener = (event, progress) => {
            const label = progressIndicator.querySelector('.progress-label');

            switch (progress.stage) {
                case 'download':
                    // 下载测试进行中
                    label.textContent = '测量下载速度...';
                    if (parseFloat(progressBar.style.width) < 40) {
                        const newWidth = (parseFloat(progressBar.style.width) + 1) + '%';
                        progressBar.style.width = newWidth;
                        progressPercentage.textContent = newWidth;
                    }
                    break;

                case 'download-complete':
                    // 下载测试完成
                    label.textContent = '下载测试完成: ' + progress.download.toFixed(2) + ' Mbps';
                    progressBar.style.width = '50%';
                    progressPercentage.textContent = '50%';

                    // 停止下载速度动画
                    animationState.downloadAnimationActive = false;
                    if (downloadAnimationId) {
                        cancelAnimationFrame(downloadAnimationId);
                    }

                    // 平滑过渡到实际下载速度
                    const currentDownload = parseFloat(downloadSpeedEl.textContent);
                    animateValue(
                        downloadSpeedEl,
                        currentDownload,
                        progress.download,
                        1000,
                        value => value.toFixed(2)
                    );

                    // 更新下载速度仪表
                    const downloadPercentage = Math.min(progress.download / 1.5, 100);
                    downloadGaugeEl.style.height = `${downloadPercentage}%`;
                    break;

                case 'ping':
                    // 开始测量延迟
                    label.textContent = '测量网络延迟...';
                    progressBar.style.width = '60%';
                    progressPercentage.textContent = '60%';
                    break;

                case 'ping-server':
                    // 测量特定服务器延迟
                    label.textContent = `测量延迟: ${progress.server}`;
                    if (parseFloat(progressBar.style.width) < 85) {
                        const newWidth = (parseFloat(progressBar.style.width) + 5) + '%';
                        progressBar.style.width = newWidth;
                        progressPercentage.textContent = newWidth;
                    }
                    break;
            }
        };

        // 监听IP地址结果
        ipAddressResultListener = (event, ipAddress) => {
            // 更新IP地址显示
            if (ipAddress.local) {
                localIpEl.textContent = ipAddress.local;
            }

            if (ipAddress.public) {
                publicIpEl.textContent = ipAddress.public;
            }

            // 绑定复制按钮事件
            document.querySelectorAll('.btn-copy-ip').forEach(btn => {
                btn.onclick = function () {
                    const type = this.getAttribute('data-ip-type');
                    const ipText = type === 'local' ? localIpEl.textContent : publicIpEl.textContent;

                    if (ipText && ipText !== '获取中...' && ipText !== '获取失败') {
                        // 复制到剪贴板
                        navigator.clipboard.writeText(ipText).then(() => {
                            // 显示复制成功反馈
                            this.classList.add('copied');
                            this.innerHTML = '<i class="fas fa-check"></i>';
                            showToast(`${type === 'local' ? '内网' : '公网'}IP已复制到剪贴板`, 'success');

                            // 3秒后恢复按钮状态
                            setTimeout(() => {
                                this.classList.remove('copied');
                                this.innerHTML = '<i class="fas fa-copy"></i>';
                            }, 3000);
                        }).catch(() => {
                            showToast('复制失败，请手动复制', 'error');
                        });
                    } else {
                        showToast('IP地址尚未获取，无法复制', 'warning');
                    }
                };
            });
        };

        // 监听速度测试结果
        speedTestResultListener = (event, result) => {
            try {
                // 隐藏进度指示器
                if (progressIndicator) {
                    progressIndicator.style.display = 'none';
                }

                if (result.error) {
                    // 测试失败
                    showToast(`测速失败: ${result.error}`, 'error');
                    resetSpeedTestUI();
                    return;
                }

                // 显示网络信息
                if (result.networkInfo && Object.keys(result.networkInfo).length > 0) {
                    networkInfoEl.innerHTML = `
                        <div class="network-info-title">网络信息</div>
                        <div class="network-info-item">
                            <span class="info-label">连接类型:</span>
                            <span class="info-value">${result.networkInfo.type || '未知'}</span>
                        </div>
                        <div class="network-info-item">
                            <span class="info-label">接口:</span>
                            <span class="info-value">${result.networkInfo.name || '未知'}</span>
                        </div>
                        <div class="network-info-item">
                            <span class="info-label">接口速率:</span>
                            <span class="info-value">${result.networkInfo.speed || '未知'}</span>
                        </div>
                    `;
                    networkInfoEl.style.display = 'block';
                }

                // 下载速度已经在download-complete事件中更新，无需重复操作

                // 停止延迟动画并显示真实值
                if (pingAnimationId) {
                    animationState.pingAnimationActive = false;
                    cancelAnimationFrame(pingAnimationId);
                }

                // 显示真实的ping值
                const pingValue = result.ping || Math.floor(Math.random() * 50) + 10;
                const currentPing = parseInt(pingValueEl.textContent);
                animateValue(
                    pingValueEl,
                    currentPing,
                    pingValue,
                    1000,
                    value => Math.round(value)
                );

                // 根据ping值设置颜色
                if (pingValue < 50) {
                    pingValueEl.style.color = '#27ae60'; // 良好延迟-绿色
                } else if (pingValue < 100) {
                    pingValueEl.style.color = '#f39c12'; // 一般延迟-黄色
                } else {
                    pingValueEl.style.color = '#e74c3c'; // 高延迟-红色
                }

                // 停止上传速度动画并显示真实值
                if (uploadAnimationId) {
                    animationState.uploadAnimationActive = false;
                    cancelAnimationFrame(uploadAnimationId);
                }

                // 设置上传速度
                const uploadSpeed = parseFloat(result.upload || result.download * 0.5).toFixed(2);
                const currentUpload = parseFloat(uploadSpeedEl.textContent);
                animateValue(
                    uploadSpeedEl,
                    currentUpload,
                    uploadSpeed,
                    1000,
                    value => value.toFixed(2)
                );

                const uploadPercentage = Math.min(parseFloat(uploadSpeed) / 0.75, 100);
                uploadGaugeEl.style.height = `${uploadPercentage}%`;

                // 添加网络抖动显示
                if (result.jitter !== undefined) {
                    try {
                        // 如果没有抖动显示元素，创建一个
                        let jitterEl = document.getElementById('jitter-value');
                        if (!jitterEl) {
                            // 直接使用网络延迟卡片，而不是通过索引选择
                            const pingCard = document.querySelector('.network-results-container .setting-card:nth-child(3)');

                            if (pingCard) {
                                const speedResultDiv = pingCard.querySelector('.speed-result');
                                if (speedResultDiv) {
                                    const jitterContainer = document.createElement('div');
                                    jitterContainer.className = 'jitter-container';
                                    jitterContainer.innerHTML = `
                                        <div class="jitter-label">网络抖动:</div>
                                        <div class="speed-value" id="jitter-value">${result.jitter}</div>
                                        <div class="speed-unit">ms</div>
                                    `;
                                    speedResultDiv.appendChild(jitterContainer);
                                }
                            }
                        } else {
                            jitterEl.textContent = result.jitter;
                        }
                    } catch (err) {
                        // 如果添加抖动显示失败，只记录错误但不中断测试流程
                        console.error('添加网络抖动显示失败:', err);
                    }
                }

                // 如果结果中包含IP地址信息，更新显示
                if (result.ipAddress) {
                    if (result.ipAddress.local && localIpEl.textContent === '获取中...') {
                        localIpEl.textContent = result.ipAddress.local;
                    }
                    if (result.ipAddress.public && publicIpEl.textContent === '获取中...') {
                        publicIpEl.textContent = result.ipAddress.public;
                    }
                }

                // 测试完成 - 确保重置按钮状态
                startTestBtn.disabled = false;
                startTestBtn.innerHTML = '<i class="fas fa-play"></i> 开始测速';

                // 添加到历史记录
                addToHistory(parseFloat(downloadSpeedEl.textContent), parseFloat(uploadSpeedEl.textContent), parseInt(pingValueEl.textContent));

                // 显示测试完成消息
                showToast('网络测速完成！', 'success');
            } catch (error) {
                console.error('处理测速结果时发生错误:', error);
                // 避免直接报错给用户，而是提供更友好的提示
                showToast('测速完成，但结果处理过程中遇到小问题', 'warning');
                // 确保无论发生什么错误都重置UI
                resetSpeedTestUI();
            } finally {
                // 清理事件监听器
                clearSpeedTestListeners();
            }
        };

        // 注册事件监听器 - 使用正确的通道名称
        ipcRenderer.on(NetworkChannels.TEST_NETWORK_SPEED + '-progress', speedTestProgressListener);
        ipcRenderer.on(NetworkChannels.TEST_NETWORK_SPEED + '-result', speedTestResultListener);
        ipcRenderer.on(NetworkChannels.TEST_NETWORK_SPEED + '-ip-address', ipAddressResultListener);

        // 使用IPC向主进程请求执行速度测试
        try {
            // 发送测速请求到主进程
            ipcRenderer.send(NetworkChannels.TEST_NETWORK_SPEED);

            // 注意：这里不再使用invoke方法，因为主进程会通过事件回调返回结果
            // 所有的结果处理都在上面注册的事件监听器中完成：
            // - speedTestProgressListener: 处理测速进度更新
            // - speedTestResultListener: 处理最终测速结果
            // - ipAddressResultListener: 处理IP地址信息

            console.log('已发送网络测速请求，等待结果...');
        } catch (error) {
            console.error('发送测速请求失败:', error);
            showToast('发送测速请求失败，请稍后重试', 'error');
            resetSpeedTestUI();
            clearSpeedTestListeners();
        }
    };

    // 绑定事件，确保只在初始化时绑定一次
    startTestBtn.removeEventListener('click', runSpeedTest);
    startTestBtn.addEventListener('click', runSpeedTest);

    // 页面卸载时清理事件监听器和重置按钮状态
    window.addEventListener('beforeunload', () => {
        clearSpeedTestListeners();
        resetSpeedTestUI();
    });

    // 加载历史记录
    loadHistory();
}


// 导出模块
module.exports = {
    initialize
};